using System;
using System.ComponentModel;
using System.Runtime.Remoting;

namespace MefBasic.Threading
{
    public class BackgroundWorkerWrapper:IBackgroundWorker
    {
        private readonly BackgroundWorker _worker;

        public BackgroundWorkerWrapper()
        {
            _worker=new BackgroundWorker();
            _worker.Disposed += WorkerDisposed;
            _worker.DoWork += WorkerDoWork;
            _worker.ProgressChanged += WorkerProgressChanged;
            _worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
        }

        void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            OnRunWorkerCompleted(e);
        }

        protected virtual void OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
        {
            if (RunWorkerCompleted != null)
            {
                IsWorkerBusy = false;
                RunWorkerCompleted(this, e);
            }
        }

        void WorkerProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            OnProgressChanged(e);
        }

        protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
        {
            if(ProgressChanged!=null)
            {
                ProgressChanged(this, e);
            }
        }

        void WorkerDoWork(object sender, DoWorkEventArgs e)
        {
            OnDoWork(e);
        }

        protected virtual void OnDoWork(DoWorkEventArgs args)
        {
            if(DoWork!=null)
            {
                IsWorkerBusy = true;
                DoWork(this, args);
                IsWorkerBusy = false;
            }
        }

        void WorkerDisposed(object sender, EventArgs e)
        {
            OnDisposed(e);
        }

        protected virtual void OnDisposed(EventArgs e)
        {
            if(Disposed!=null)
            {
                Disposed(this,e);
            }
        }

        #region Implementation of IBackgroundWorker

        public virtual void CancelAsync()
        {
            _worker.CancelAsync();
        }

        public virtual void ReportProgress(int percentProgress)
        {
            _worker.ReportProgress(percentProgress);
        }

        public virtual void ReportProgress(int percentProgress, object userState)
        {
            _worker.ReportProgress(percentProgress,userState);
        }

        public virtual void RunWorkerAsync()
        {            
            _worker.RunWorkerAsync();
        }

        public virtual void RunWorkerAsync(object argument)
        {
            _worker.RunWorkerAsync(argument);
        }
        public virtual bool CancellationPending
        {
            get { return _worker.CancellationPending; }
        }

        public virtual bool IsBusy
        {
            get { return _worker.IsBusy; }
        }

        public virtual bool WorkerReportsProgress
        {
            get { return _worker.WorkerReportsProgress; }
            set { _worker.WorkerReportsProgress=value; }
        }

        public virtual bool WorkerSupportsCancellation
        {
            get { return _worker.WorkerSupportsCancellation; }
            set { _worker.WorkerSupportsCancellation=value; }
        }

        public virtual ISite Site
        {
            get { return _worker.Site; }
            set { _worker.Site=value; }
        }

        public virtual IContainer Container
        {
            get { return _worker.Container; }
        }

        public bool IsWorkerBusy { get; set; }

        public event DoWorkEventHandler DoWork;
        public event ProgressChangedEventHandler ProgressChanged;
        public event RunWorkerCompletedEventHandler RunWorkerCompleted;
        public virtual void Dispose()
        {
            _worker.Dispose();
        }

        public event EventHandler Disposed;
        public virtual object GetLifetimeService()
        {
            return _worker.GetLifetimeService();
        }

        public virtual object InitializeLifetimeService()
        {
            return _worker.InitializeLifetimeService();
        }

        public virtual ObjRef CreateObjRef(Type requestedType)
        {
            return _worker.CreateObjRef(requestedType);
        }

        #endregion
    }
}